import os

def run_wsgiref(app, host, port, **kwargs):
    from wsgiref.simple_server import make_server, WSGIRequestHandler
    class QuietHandler(WSGIRequestHandler):
        def log_request(*args, **kw): pass
    srv = make_server(host, port, app, handler_class=QuietHandler)
    srv.serve_forever()

def run_cherrypy(app, host, port,
            server_name = None,
            numthreads = 10, # thread pool min threads.
            max = 15, # thread pool max threads.
            socket_timeout = 0.001, # seconds. when socket_timeout is 0, cherry server fails: resource temporarily unavailable.
            shutdown_timeout = 5, # max seconds to wait before shutdown
            max_request_body_size = 2*1024*1024,
            max_request_header_size = 20*1024,
            request_queue_size = 64, # socket.listen(request_queue_size) socket.SOMAXCONN: 128
    ):
    '''
    cherrypy server is a synchoronous server, socket timeout defaults 
    10 secondes. 
    
    ThIS MEANS that every thread will wait 10 seconds after it serves a http/1.1 request.
    so concurrent connections it can handle are limited by its thread pool size,
    so the only practical way to run it in high concurrent environments is run it behind nginx,
    close connection immediately after it has been served.

    http://www.cherrypy.org/wiki/ServerAPI
    '''
    try:
        from cheroot.server import CherryPyWSGIServer
    except:
        from cherrypy.wsgiserver import CherryPyWSGIServer

    assert max >= numthreads
    assert socket_timeout > 0

    server = CherryPyWSGIServer(
                (host, port), 
                app, 
                server_name = server_name,
                numthreads = numthreads,
                max = max,
                request_queue_size = request_queue_size,
                timeout = socket_timeout,
                shutdown_timeout = shutdown_timeout
            )
    server.max_request_body_size = max_request_body_size
    server.max_request_header_size = max_request_header_size
    server.start()

def run(app, host='127.0.0.1', port=8080, server='wsgiref', autoreload=False, quiet=True, **kwargs):
    if not quiet:
        if not autoreload or os.environ.get('RUN_MAIN') == 'true':
            print("Server starting up (using \x1b[32m%s\x1b[0m)..." % server)
            print("Listening on http://%s:%d/" % (host, port))
            print("Use Ctrl-C to quit.")
            print()
        else:
            print("autoreload starting up...")

    func = globals()['run_' + server]
    try:
        if autoreload:
            from bodhi.utils.autoreload import main
            main(lambda: func(app, host=host, port=port, **kwargs))
        else:
            func(app, host=host, port=port, **kwargs)
    except KeyboardInterrupt:
        if not quiet: 
            print("Shutting Down...")

